#include "pch.h"
#include "RenderTarget.h"
#include "../DirectX/DirectXHelper.h"


RenderTarget::RenderTarget(bool createDepthStencilBuffer, bool hasRelativeSize, float width, float height, DXGI_FORMAT format, DXGI_FORMAT depthStencilFormat) :
    m_hasDepthStencilBuffer(createDepthStencilBuffer),
    m_hasRelativeSize(hasRelativeSize),
    m_width(width),
    m_height(height),
    m_format(format),
    m_depthStencilFormat(depthStencilFormat),
    m_renderTargetView(),
    m_shaderResourceView(),
    m_depthStencilView()
{
}

void RenderTarget::Create(ID3D11Device* device, float backBufferWidth, float backBufferHeight)
{
    D3D11_TEXTURE2D_DESC texDesc;
    texDesc.Width = static_cast<UINT>(m_hasRelativeSize ? backBufferWidth * m_width : m_width);
    texDesc.Height = static_cast<UINT>(m_hasRelativeSize ? backBufferHeight * m_height : m_height);
    texDesc.MipLevels = 1;
    texDesc.ArraySize = 1;
    texDesc.Format = m_format;
    texDesc.SampleDesc.Count = 1;
    texDesc.SampleDesc.Quality = 0;
    texDesc.Usage = D3D11_USAGE_DEFAULT;
    texDesc.BindFlags = D3D11_BIND_SHADER_RESOURCE | D3D11_BIND_RENDER_TARGET;
    texDesc.CPUAccessFlags = 0;
    texDesc.MiscFlags = 0;

    Microsoft::WRL::ComPtr<ID3D11Texture2D> texture;
    DX::ThrowIfFailed(device->CreateTexture2D(&texDesc, nullptr, &texture));

    D3D11_RENDER_TARGET_VIEW_DESC rtvDesc = {};
    rtvDesc.Format = m_format;
    rtvDesc.ViewDimension = D3D11_RTV_DIMENSION_TEXTURE2D;
    rtvDesc.Texture2D.MipSlice = 0;

    DX::ThrowIfFailed(device->CreateRenderTargetView(texture.Get(), &rtvDesc, &m_renderTargetView));

    D3D11_SHADER_RESOURCE_VIEW_DESC srvDesc = {};
    srvDesc.Format = m_format;
    srvDesc.ViewDimension = D3D11_SRV_DIMENSION_TEXTURE2D;
    srvDesc.Texture2D.MostDetailedMip = 0;
    srvDesc.Texture2D.MipLevels = 1;

    DX::ThrowIfFailed(device->CreateShaderResourceView(texture.Get(), &srvDesc, &m_shaderResourceView));

    if (m_hasDepthStencilBuffer)
    {
        D3D11_TEXTURE2D_DESC depthStencilTexDesc = {};
        depthStencilTexDesc.Width = static_cast<UINT>(m_hasRelativeSize ? m_width * backBufferWidth : m_width);
        depthStencilTexDesc.Height = static_cast<UINT>(m_hasRelativeSize ? m_height * backBufferHeight : m_height);
        depthStencilTexDesc.MipLevels = 1;
        depthStencilTexDesc.ArraySize = 1;
        depthStencilTexDesc.Format = m_depthStencilFormat;
        depthStencilTexDesc.SampleDesc.Count = 1;
        depthStencilTexDesc.SampleDesc.Quality = 0;
        depthStencilTexDesc.Usage = D3D11_USAGE_DEFAULT;
        depthStencilTexDesc.BindFlags = D3D11_BIND_DEPTH_STENCIL;
        depthStencilTexDesc.CPUAccessFlags = 0;
        depthStencilTexDesc.MiscFlags = 0;

        D3D11_DEPTH_STENCIL_VIEW_DESC dsvDesc = {};
        dsvDesc.Format = depthStencilTexDesc.Format;
        dsvDesc.ViewDimension = D3D11_DSV_DIMENSION_TEXTURE2D;
        dsvDesc.Texture2D.MipSlice = 0;

        DX::ThrowIfFailed(device->CreateTexture2D(&depthStencilTexDesc, nullptr, &texture));
        DX::ThrowIfFailed(device->CreateDepthStencilView(texture.Get(), &dsvDesc, &m_depthStencilView));
    }
}
